/**
 * Copyright (c) 2018 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package io.renren.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.renren.config.GenConfig;
import io.renren.dao.GeneratorDao;
import io.renren.utils.GenUtils;
import io.renren.utils.PageUtils;
import io.renren.utils.Query;
import io.renren.utils.SqlHelper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;

/**
 * 代码生成器
 * 
 * @author Mark sunlightcs@gmail.com
 */
@Service
public class SysGeneratorService {
	@Autowired
	private GeneratorDao generatorDao;
	@Autowired
	private JdbcTemplate jdbcTemplate;

	public PageUtils queryList(Query query) {

		String tableName = (String) query.get("tableName");
		if (StringUtils.isNotBlank(tableName)) {
			List tableNames = SqlHelper.splitBySpace( tableName );
			if (tableNames != null && tableNames.size() > 0) {
				query.put("tableNames", tableNames);
				query.remove("tableName");
			}

		}

		Page<?> page = PageHelper.startPage(query.getPage(), query.getLimit());
		List<Map<String, Object>> list = generatorDao.queryList(query);


		return new PageUtils(list, (int)page.getTotal(), query.getLimit(), query.getPage());
	}

	public Map<String, String> queryTable(String dbName, String tableName) {
		return generatorDao.queryTable(dbName, tableName);
	}

	public List<Map<String,String>> queryColumns(String dbName, String tableName) {
		List<Map<String,String>> columns = generatorDao.queryColumns(dbName, tableName);

		Map<String,Map<String,String>> columnMapping = new HashMap<>();
		for (Map<String,String> c : columns) {
			columnMapping.put(c.get("columnName").toUpperCase(), c);
		}

		SqlRowSet rowSet = jdbcTemplate.queryForRowSet("select * from "+ dbName + "." +tableName +" limit 0");

		List<Map<String,String>> list = new ArrayList<>();

		SqlRowSetMetaData metaData = rowSet.getMetaData();

		int columnCount = metaData.getColumnCount();
		for (int i = 1; i <= columnCount; i++) {
			Map<String,String> fieldMap = new HashMap<>();
			fieldMap.put("columnName", metaData.getColumnName( i ).toUpperCase());
			fieldMap.put("sqlType", String.valueOf(metaData.getColumnType(i)));
			fieldMap.put("dataType", metaData.getColumnTypeName( i ));
			fieldMap.put("catalogName", metaData.getCatalogName(i));
			fieldMap.put("columnClassName", metaData.getColumnClassName(i));
			fieldMap.put("columnLabel", metaData.getColumnLabel(i));
			fieldMap.put("precision", String.valueOf(metaData.getPrecision(i)));
			fieldMap.put("scale", String.valueOf(metaData.getScale(i)));
			fieldMap.put("tableName", metaData.getTableName(i));

			Map<String,String> cols = columnMapping.get( metaData.getColumnName( i ).toUpperCase() );
			fieldMap.put("columnComment", cols.get("columnComment"));
			fieldMap.put("columnKey", cols.get("columnKey"));
			fieldMap.put("extra", cols.get("extra"));

			list.add( fieldMap );
		}

		return  list;

	}

	public byte[] generatorCode(String dbName, String[] tableNames) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);

		for(String tableName : tableNames){
			//查询表信息
			Map<String, String> table = queryTable(dbName, tableName);
			//查询列信息
			List<Map<String, String>> columns = queryColumns(dbName, tableName);
			//生成代码
			GenUtils.generatorCode(table, columns, zip);
		}
		IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}

	public byte[] generatorCode(String dbName, String[] tableNames, GenConfig genConfig) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);

		for(String tableName : tableNames){
			//查询表信息
			Map<String, String> table = queryTable(dbName, tableName);
			//查询列信息
			List<Map<String, String>> columns = queryColumns(dbName, tableName);
			//生成代码
			try {
				GenUtils.generatorCode(genConfig, table, columns, zip);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}

}
